#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "file_struct.h"
#include "user_define.h"
#include "node_define.h"
#include "data_define.h"

#include "sensor.h"
extern struct timeval time_val;

float average_temp=3100.0;
int var_space=50;
float span=1000.0;


int freq= 10;
int freq_time=0;
int data_num;

char Data_Buf[1024];
int max_data = 250;

RECORD(DATA_DEFINE,ENV_DATA) env_data;

int sensor_init(void * sub_proc,void * para)
{
	int ret;
    DIR * dir;    
	// add youself's plugin init func here
    Memset(&env_data,0,sizeof(env_data));

    dir = opendir("env_data");
    if(dir==NULL)
        system("mkdir env_data");

	return 0;
}

int sensor_start(void * sub_proc,void * para)
{
	int ret;
	int i;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here

	RECORD(NODE_DEFINE,CONFIG) * node_config;

	node_config = proc_share_data_getpointer();	
    env_data.node_name = dup_str(node_config->node_name,DIGEST_SIZE);

	while(1)
	{
		usleep(sensor_val.tv_usec);
        
	    node_config = proc_share_data_getpointer();	
        if(node_config == NULL)
            return -EINVAL;
        if(node_config->node_state == NODE_WORKING)
            proc_sensor_test(sub_proc,NULL);
	}
	
	return 0;
}

int output_env_data(void * sub_proc,void * recv_msg)
{
    int ret;
    char * temp_name ="env_data/temp_env_data_file";
    int fd;
    BYTE digest[DIGEST_SIZE];
    char new_filename[DIGEST_SIZE*2];
    RECORD(FILE_TRANS,REQUEST) * file_req;

    fd=open(temp_name,O_WRONLY|O_CREAT|O_TRUNC,0666);
    if(fd<0)
        return fd;
    ret=write(fd,Data_Buf,env_data.data_num* sizeof(int));
    if(ret<0)
        return ret;
    close(fd);

    ret=convert_uuidname(temp_name,DIGEST_SIZE,env_data.data_uuid,new_filename);
    if(ret<0)
        return ret;

	void * new_msg;
    // send env_data struct
	new_msg=message_create(TYPE_PAIR(DATA_DEFINE,ENV_DATA),recv_msg);
    if(new_msg==NULL)
        return -EINVAL;
    ret=message_add_record(new_msg,&env_data);
	if(ret<0)
		return ret;
	ret=ex_module_sendmsg(sub_proc,new_msg);

    // build file_req struct
    file_req=Talloc0(sizeof(*file_req));
    if(file_req==NULL)
        return -ENOMEM;
    Memcpy(file_req->uuid,env_data.data_uuid,DIGEST_SIZE);
    file_req->filename=dup_str(new_filename,DIGEST_SIZE*3);    
    file_req->requestor = NULL;
    // send file_request message

    new_msg= message_create(TYPE_PAIR(FILE_TRANS,REQUEST),recv_msg);
    if(new_msg==NULL)
        return -EINVAL;
    ret=message_add_record(new_msg,file_req);
	if(ret<0)
		return ret;
	ret=ex_module_sendmsg(sub_proc,new_msg);

	return ret;
}
int proc_sensor_test(void * sub_proc,void * recv_msg)
{
	int ret;
	int i;
    int base_temp;
    char var_temp;
    time_t curr_time;
    RECORD(NODE_DEFINE,CONFIG) * node_config;

	node_config = proc_share_data_getpointer();	
    
        
    if((freq_time % node_config->interval) != 0)
    {
        freq_time++;
        return 0;
    }
    else
    {
        freq_time++;
    }

    if(env_data.data_num == 0)
    {
        curr_time = time(&curr_time)-node_config->origin;
        env_data.start_time=curr_time;
        env_data.interval=node_config->interval;
    }

    base_temp=(int)average_temp;

    RAND_bytes(&var_temp,sizeof(char));

    if(var_temp>0)
        var_temp%=var_space;
    else
        var_temp=-((-var_temp)%var_space);
    average_temp += (float)var_temp/span;

    *((int *)Data_Buf+env_data.data_num)= base_temp+var_temp;
    env_data.data_num++;

    if(env_data.data_num == max_data)
    {
        ret = output_env_data(sub_proc,recv_msg);
        env_data.data_num=0;
        return ret;
    }

    return 0;
}
